import Singleton from "../core/design-pattern/Singleton";
import StorageMgr from "../core/manager/StorageMgr";
import FrameLog from "../extensions/FrameLog";
import DateUtil from "../utils/DateUtil";
import StroageConst from "./const/StroageConst";

const { ccclass, property } = cc._decorator;
type User = {
    __userInfo: {
        headimgurl: String,
        nickname: String,
        sex: String,
        language: String,
        province: String,
        city: String,
        country: String
    },
    __rankInfo: {
        key_1: any
    },
    [key: string]: any,  // 自定义数据,任意类型
}
@ccclass
export default class UserData extends Singleton{
   
    private _user: User = {
        __userInfo: {
            headimgurl: "",
            nickname: "",
            sex: "",
            language: "",
            province: "",
            city: "",
            country: "",
        },
        __rankInfo: {//世界排行榜数据
            key_1: 0
        },
        id: "",
        lv: 1,
        score: 0,
        loginDate: 0,//登录
        version: 0,//注册是版本号
        signDay: 0,//签到
        coin: 0,//金币
        energy: 6,//体力
        energytimer: 0,//使用energy的时间
        skinId: 1,//当前皮肤值
        isNewPlayer: false,//是否是新手
    }
    public isLocal: boolean = true;     //是否使用了本地缓存数据
    private readonly update_duration: number = 20;//玩家数据更新时长
    private _tempTime: number = 0;
    private _isUpdate: boolean = false; //玩家数据在时长内是否有更新
    public init() {
        let data = StorageMgr.getInstance().get(StroageConst.userData)
        let nowDate = Date.now()
        if (data) {
            if (!DateUtil.compare(nowDate, data.loginDate)) {
                //重置微信分享视频次数控制
            }
            //有数据不是新手
            this.setProperty({ isNewPlayer: false })
            //更新登录时间
            data.loginDate = nowDate
            this.setProperty(data)
        }
        else {
            this.isLocal = false;//获取远程数据
            this._user.loginDate = nowDate;
            // this._user.version = WxNet.inst.version
        }
    }
    /**
     * 获取玩家属性
     * @param key 
     */
    public getProperty(key: string): any {
        if (this._user.__userInfo.hasOwnProperty(key)) {
            return this._user.__userInfo[key]
        }
        else if (this._user.__rankInfo.hasOwnProperty(key)) {
            return this._user.__rankInfo[key]
        }
        else if (this._user.hasOwnProperty(key)) {
            return this._user[key]
        }
        return null;
    }
    /**
     * 设置玩家属性
     * @param param  key值：value值
     */
    public setProperty(param: { [key: string]: any }) {
        if (param == null) return;
        for (let key in param) {
            if (this._user.__userInfo.hasOwnProperty(key)) {
                this._user.__userInfo[key] = param[key];
            }
            else if (this._user.__rankInfo.hasOwnProperty(key)) {
                this._user.__rankInfo[key] = param[key];
            }
            else if (this._user.hasOwnProperty(key)) {
                this._user[key] = param[key];
            }
        }
        this.saveUserData()
        // ClientEvent.inst.emit(EventType.USER_DATA_UPDATE)
    }
    /**
     *  保存玩家数据
     */
    private saveUserData() {
        this._isUpdate = true;
        StorageMgr.getInstance().set(StroageConst.userData, this._user)
    }
    /**
    * 上传玩家数据
    */
    private postUserData() {
        let param = Object.create({})
        param.user = this._user
        // WxNet.inst.postUser(param)
    }
    //更新数据
    public update(dt: number) {
        this._tempTime += dt;
        if (this._tempTime >= this.update_duration) {
            this._tempTime = 0;
            if (this._isUpdate) {
                let data: KVData = {
                    key: `score`,
                    value: `` + this.getProperty("score")
                }
                // 分数上传后台  data
                this._isUpdate = false;
                this.postUserData()
            }
        }
    }
    /**
     * 设置用户资产
     * @param key 
     * @param value 
     * @param canNegative 是否允许负数
     */
    public setValue(key: string, value: number, canNegative: boolean = false) {
        value = parseFloat(value.toFixed(2))
        let isAdd = value > 0 ? true : false;
        let myValue: any = this.getProperty(key)
        if (typeof myValue == "number") {//数据类型检查
            //数据范围检查 
            //1.减法：出现负数  2.加法：超过最大值
            if (isAdd) {

            } else {
                if (myValue + value >= 0 || canNegative) {
                    this.setProperty({ key: myValue + value });
                    // ClientEvent.inst.emit(EventType.USER_PROPERTY_UPDATE, { key })
                    return true;
                }
                else {
                    FrameLog.error("数值变化为不合法的负数，此次更改失效")
                }
            }

        }
        else {
            FrameLog.error("key不是数字类型！")
        }
        return false;
    }
}
